#include <stdlib.h>
#include <string.h>
#include <directfb.h>
#include "dtk_priv.h"
#include "dtk_stage.h"
#include "dtk_stage_window.h"

DTKStageWindow* dtk_stage_window_create (DTKStageDescription* desc)
{
    DFBResult               ret = DFB_OK;
    DFBRectangle            rect;
    DFBWindowDescription    dsc;
    DFBWindowOptions        options;
    DFBDisplayLayerConfig   dlc;
    IDirectFBSurface        *surface = NULL;
    IDirectFBDisplayLayer*  layer = NULL;
    IDirectFBEventBuffer*   event_buffer;
    DFBWindowID             id;
    DTKStageWindow* stage_window;

    stage_window = (DTKStageWindow*) malloc (sizeof(DTKStageWindow));
    memset (stage_window, 0, sizeof(DTKStageWindow));

    dsc.flags = DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH |
                DWDESC_HEIGHT | DWDESC_CAPS;
    dsc.posx = desc->x;
    dsc.posy = desc->y;
    dsc.width = desc->width;
    dsc.height = desc->height;
    dsc.caps = DWCAPS_ALPHACHANNEL;

    layer = dtk_get_default_layer();
    ret = layer->CreateWindow(layer, &dsc, &stage_window->window);
    if (ret)
    {
        DirectFBError ("window_new:IDirectFBWindow::CreateWindow() failed",
                    ret);
        free(stage_window);
        return NULL;
    }
    event_buffer = dtk_get_default_eventbuffer();
    event_buffer->AddRef (event_buffer);
    ret = stage_window->window->AttachEventBuffer(stage_window->window,
                                    event_buffer);
    if (ret)
    {
        DirectFBError ("window_new:IDirectFBWindow::AttachEventBuffer() failed",
                    ret);
        free(stage_window);
        return NULL;
    }    

    return stage_window;
}

void dtk_stage_window_destroy(DTKStageWindow* stage_window)
{
    if (stage_window == NULL)
    {
        return;
    }

    free (stage_window);
    return;
}

DBoolean dtk_stage_window_set_property(DTKStageWindow* stage_window,
                                                const DString key, void* value,
                                                void** ret_old_value)
{
    DFBResult ret;

    if (stage_window == NULL || key == NULL)
    {
        return DTK_FALSE;
    }

    ret = stage_window->window->SetProperty (stage_window->window,
                                key, value, ret_old_value);

    return DTK_TRUE;
}

DBoolean dtk_stage_window_show(DTKStageWindow* stage_window,
                                    DInt opacity)
{
    if (NULL == stage_window)
    {
        return DTK_FALSE;
    }

    stage_window->window->SetOpacity(stage_window->window, opacity);

    return DTK_TRUE;
}

IDirectFBSurface* dtk_stage_window_get_surface (DTKStageWindow* stage_window)
{
    IDirectFBSurface* surface;
    DFBResult ret;

    ret = stage_window->window->GetSurface (stage_window->window, &surface);
    if (DFB_OK != ret)
    {
        return NULL;
    }

    return surface;
}